package api

import (
	"fmt"
	"strconv"
	"vblog/apps/blog"
	"vblog/apps/token"
	"vblog/apps/user"
	"vblog/conf"
	"vblog/ioc"
	"vblog/middleware"
	"vblog/response"

	"github.com/gin-gonic/gin"
)

// 博客创建接口 CreateBlog: POST /vblog/api/v1/blogs
// 博客列表接口 Blog: GET /vblog/api/v1/blogs?page_size=10&page_number=1&....
// 博客全量修改接口 Blog: PUT /vblog/api/v1/blogs/{id}
// 博客增量修改接口 Blog: PATCH /vblog/api/v1/blogs/{id}
// 博客删除修改接口 Blog: DELETE /vblog/api/v1/blogs/{id}

// init函数
// 注册到ioc
func init() {
	ioc.Api.Registry(blog.AppName, &BlogApiHandler{})
}

type BlogApiHandler struct {
	Blog blog.Service
}

// IOC中Init该方法
// 获取ioc角色
// 注册路由
func (h *BlogApiHandler) Init() error {
	h.Blog = ioc.Controller.Get(blog.AppName).(blog.Service)
	// blog/api/v1 + blog.AppName
	appRouter := conf.C().APP.RootRouter().Group(blog.AppName)
	h.Registry(appRouter)

	return nil
}

func (h *BlogApiHandler) Registry(appRouter gin.IRouter) {
	appRouter.GET("/", h.QueryBlog)
	appRouter.GET("/:id", h.DescribeBlog)

	appRouter.Use(middleware.Auth)
	appRouter.POST("/", middleware.RequireRole(user.ROLE_AUTHOR), h.CreateBlog)
	appRouter.PUT("/:id", middleware.RequireRole(user.ROLE_AUTHOR), h.UpdateBlog)
	appRouter.PATCH("/:id", middleware.RequireRole(user.ROLE_AUTHOR), h.UpdateBlog)
	appRouter.POST("/:id/status", middleware.RequireRole(user.ROLE_AUTHOR), h.UpdateBlogStatus)
	appRouter.DELETE("/:id", middleware.RequireRole(user.ROLE_AUTHOR), h.DeleteBlog)

}

// CreateBlog
func (h *BlogApiHandler) CreateBlog(c *gin.Context) {
	req := blog.NewCreateBlogRequest()
	if err := c.BindJSON(req); err != nil {
		response.Failed(c, err)
		return
	}
	// 从gin context中获取 token
	v, ok := c.Get(token.GinCookieName)
	// c.Cookie(token.GinCookieName)
	if !ok {
		response.Failed(c, fmt.Errorf("token 无效"))
		return
	}

	req.CreateBy = v.(*token.Token).Username

	res, err := h.Blog.CreateBlog(c, req)
	if err != nil {
		response.Failed(c, err)
		return
	}
	response.Success(c, res)
}

// QueryBlog
func (h *BlogApiHandler) QueryBlog(c *gin.Context) {
	pageSize, _ := strconv.Atoi(c.Query("page_size"))
	pageNumber, _ := strconv.Atoi(c.Query("page_number"))
	keywords := c.Query("keywords")

	req := blog.NewQueryBlogRequest()
	req.Keywords = keywords
	if pageNumber > 0 {
		req.PageNumber = pageNumber
	}
	if pageSize > 0 {
		req.PageSize = pageSize

	}

	res, err := h.Blog.QueryBlog(c, req)
	if err != nil {
		response.Failed(c, err)
		return
	}

	response.Success(c, res)

}

// UpdateBlog
func (h *BlogApiHandler) UpdateBlog(c *gin.Context) {

	id, _ := strconv.Atoi(c.Param("id"))
	req := blog.NewUpdateBlogRequest(id)

	//TODO 这个地方id 会保留？？？
	if err := c.BindJSON(req); err != nil {
		response.Failed(c, err)
		return
	}

	fmt.Printf("%#v", req)

	res, err := h.Blog.UpdateBlog(c, req)
	if err != nil {
		response.Failed(c, err)
		return
	}
	response.Success(c, res)
}

// DescribeBlog
func (h *BlogApiHandler) DescribeBlog(c *gin.Context) {

	// 验证token
	accessToken, _ := c.Cookie(token.CookieName)
	ioc.Controller.Get(token.AppName).(token.Service).ValidateToken(c, token.NewValidateTokenRequest(accessToken))

	id, _ := strconv.Atoi(c.Param("id"))
	req := blog.NewDescribeBlogRequest(id)
	res, err := h.Blog.DescribeBlog(c, req)
	if err != nil {
		response.Failed(c, err)
		return
	}

	response.Success(c, res)
}

// DeleteBlog
func (h *BlogApiHandler) DeleteBlog(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	req := blog.NewDeleteBlogRequest(id)
	res, err := h.Blog.DeleteBlog(c, req)
	if err != nil {
		response.Failed(c, err)
		return
	}
	response.Success(c, res)

}

// UpdateBlogStatus
func (h *BlogApiHandler) UpdateBlogStatus(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	req := blog.NewUpdateBlogStatusRequest(id)
	if err := c.BindJSON(req); err != nil {
		response.Failed(c, err)
		return
	}
	fmt.Println(req.Status)
	res, err := h.Blog.UpdateBlogStatus(c, req)

	if err != nil {
		response.Failed(c, err)
		return
	}
	response.Success(c, res)
}
